package com.cspm.ahjy.bc.office.util;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.regex.Pattern;

import org.springframework.util.StringUtils;

import sun.misc.BASE64Decoder;

import com.drew.imaging.jpeg.JpegMetadataReader;
import com.drew.imaging.jpeg.JpegProcessingException;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.Tag;

/**
 * 图像文件处理
 * 
 * @author ServerZhang
 * @date 2017年9月29日
 */
public class ImageFileUtil {

	private static final DecimalFormat df = new DecimalFormat("######0.00");

	/**
	 * 检测上传的jpg图片是否合法
	 * 合法条件：格式为JPG；能获取到高、宽、高宽的分辨率dpi
	 * @param filePath
	 * @return
	 * @author ServerZhang
	 * @date 2017年10月19日
	 */
	public static Boolean jpgIsLegal(String filePath){
		File file = new File(filePath);
		if (file != null && file.isFile()) {
			return jpgIsLegal(file);
		}
		return Boolean.FALSE;
	}
	public static Boolean jpgIsLegal(File imgFile){
		Boolean jpg = isJPG(imgFile);
		if (!jpg) {
			return jpg;
		}
		Map<String, String> jpgInfor = getJpgInfor(imgFile);
		String widthStr = jpgInfor.get("ImageWidth");
		if (StringUtils.isEmpty(widthStr)) {
			return Boolean.FALSE;
		}
		String heightStr = jpgInfor.get("ImageHeight");
		if (!StringUtils.isEmpty(heightStr)) {
			return Boolean.FALSE;
		}
		String dpiWStr = jpgInfor.get("XResolution");
		if (!StringUtils.isEmpty(dpiWStr)) {
			return Boolean.FALSE;
		}
		String dpiHStr = jpgInfor.get("YResolution");
		if (!StringUtils.isEmpty(dpiHStr)) {
			return Boolean.FALSE;
		}
		return Boolean.TRUE;
	}
	
	/**
	 * 获取图片宽度
	 * 
	 * @param filePath
	 * @return
	 * @author ServerZhang
	 * @date 2017年9月29日
	 */
	@Deprecated
	public static Integer getImgWidth(String filePath) {
		return getImgWidth(new File(filePath));
	}
	@Deprecated
	public static Integer getImgWidth(File file) {
		InputStream is = null;
		BufferedImage src = null;
		int ret = -1;
		try {
			is = new FileInputStream(file);
			src = javax.imageio.ImageIO.read(is);
			ret = src.getWidth(null); // 得到源图宽
			is.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return ret;
	}

	/**
	 * 获取图片高度
	 * 
	 * @param filePath
	 * @return
	 * @author ServerZhang
	 * @date 2017年9月29日
	 */
	@Deprecated
	public static Integer getImgHeight(String filePath) {
		return getImgHeight(new File(filePath));
	}
	@Deprecated
	public static Integer getImgHeight(File file) {
		InputStream is = null;
		BufferedImage src = null;
		int ret = -1;
		try {
			is = new FileInputStream(file);
			src = javax.imageio.ImageIO.read(is);
			ret = src.getHeight(null); // 得到源图高
			is.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return ret;
	}

	/**
	 * 像素转换成厘米
	 * 
	 * @param pixel
	 * @param dpi
	 * @return
	 * @author ServerZhang
	 * @date 2017年10月18日
	 */
	public static Double pixel2CM(Integer pixel, Integer dpi) {
		Double cmValue = null;
		
		if (pixel == null || dpi == null) {
			return null;
		}
		
		cmValue = (pixel*300) / (dpi*118.11);//以300dpi为基准，计算相应值
		
		/*switch (dpi) {
		case 72:
			cmValue = pixel / 28.346;
			break;
		case 96:
			cmValue = pixel * 0.0265;
			break;
		case 300:
			cmValue = pixel / 118.11;
			break;

		default://以300dpi为基准，计算相应值
			cmValue = (pixel*300) / (dpi*118.11);
			break;
		}*/

		String format = df.format(cmValue);

		return Double.parseDouble(format);
	}

	/**
	 * 获取图片高、宽，单位为“厘米”
	 * @param jpegFile
	 * @return
	 * @author ServerZhang
	 * @date 2017年10月18日
	 */
	public static Map<String, Double> getJpgWH(File jpegFile) {
		Map<String, Double> infor = new HashMap<String, Double>();
		Integer picWidth = null;// 图片宽（像素）
		Integer picHeight = null;// 图片高（像素）
		Integer picWidthDpi = null;// 图片水平分辨率（dpi）
		Integer picHeightDpi = null;// 图片垂直分辨率（dpi）
		
		Map<String, String> jpgInfor = getJpgInfor(jpegFile);
		String widthStr = jpgInfor.get("ImageWidth");
		if (!StringUtils.isEmpty(widthStr)) {
			picWidth = Integer.parseInt(widthStr.replaceAll("pixel[s]{0,1}", ""));
		}
		String heightStr = jpgInfor.get("ImageHeight");
		if (!StringUtils.isEmpty(heightStr)) {
			picHeight = Integer.parseInt(heightStr.replaceAll("pixel[s]{0,1}", ""));
		}
		String dpiWStr = jpgInfor.get("XResolution");
		if (!StringUtils.isEmpty(dpiWStr)) {
			picWidthDpi = Integer.parseInt(dpiWStr.replaceAll("dot[s]{0,1}", ""));
		}
		String dpiHStr = jpgInfor.get("YResolution");
		if (!StringUtils.isEmpty(dpiHStr)) {
			picHeightDpi = Integer.parseInt(dpiHStr.replaceAll("dot[s]{0,1}", ""));
		}

		infor.put("width", pixel2CM(picWidth, picWidthDpi));
		infor.put("height", pixel2CM(picHeight, picHeightDpi));
		return infor;
	}

	/**
	 * 获取jpg文件的所有属性信息
	 * @param jpegFile
	 * @return
	 * @author ServerZhang
	 * @date 2017年10月18日
	 */
	public static Map<String, String> getJpgInfor(File jpegFile) {
		Map<String, String> imageInfo = new HashMap<String, String>();
		try {
			if (jpegFile.isFile()) {// 图片必须是一个文件
				Metadata metadata = JpegMetadataReader.readMetadata(jpegFile);
				for (Directory exif : metadata.getDirectories()) {
					Iterator tags = exif.getTags().iterator();
					while (tags.hasNext()) {
						Tag tag = (Tag) tags.next();
						String key = tag.getTagName().trim().replace(" ", "");
						String val = tag.getDescription().trim()
								.replace(" ", "");
						imageInfo.put(key, val);
					}
				}
			}
		} catch (JpegProcessingException e) {
			//非jpg文件
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return imageInfo;
	}

	public static void main(String[] args) {

		/*Map<String, String> imageInfo = getImageInfo("D:/WordTest/5/hehe.jpg");
		for (String key : imageInfo.keySet()) {
			System.out.println(key + " : " + imageInfo.get(key));
		}*/

		getJpgInfor(new File("D:/WordTest/4/奥运会.jpg"));
		 /*Boolean jpg = isJPG("D:/WordTest/5/haha.jpg");
		 System.out.println(jpg);*/
		// imageFile2Hex("D:/WordTest/5/hehe.jpg");
	}

	/**
	 * 判断图片是否是JPG图片
	 * 
	 * @param imgPath
	 * @return
	 * @author ServerZhang
	 * @date 2017年10月18日
	 */
	public static Boolean isJPG(String imgPath) {
		File imgFile = new File(imgPath);
		if (!imgFile.isFile()) {
			return Boolean.FALSE;
		}
		return isJPG(imgFile);
	}
	public static Boolean isJPG(File imgFile) {
		if (null == imgFile) {
			return Boolean.FALSE;
		}
		String imageFile2Hex = imageFile2Hex(imgFile);
		return imageFile2Hex.startsWith("FFD8");
	}
	public static Boolean isJPG4BinData(String binData) {
		
		if (StringUtils.isEmpty(binData)) {
			return Boolean.FALSE;
		}
		
		BASE64Decoder decoder = new BASE64Decoder();
		byte[] decodeBuffer = null;
		try {
			decodeBuffer = decoder.decodeBuffer(binData);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		if (decodeBuffer == null) {
			return Boolean.FALSE;
		}
		
		String byte2Hex = byte2Hex(decodeBuffer);
		
		return byte2Hex.startsWith("FFD8");

	}

	/**
	 * 图片文件转换成十六进制字符串
	 * 
	 * @param imagePath
	 * @return
	 * @author ServerZhang
	 * @date 2017年10月18日
	 */
	public static String imageFile2Hex(String imagePath) {
		FileInputStream fis;
		ByteArrayOutputStream bos;
		int len = 0;
		byte[] buff;
		byte[] result = null;
		try {
			fis = new FileInputStream(imagePath);
			bos = new ByteArrayOutputStream();
			buff = new byte[1024];
			while ((len = fis.read(buff)) != -1) {
				bos.write(buff, 0, len);
			}
			// 得到图片的字节数组
			result = bos.toByteArray();// 字节数组转成十六进制
		} catch (IOException e) {
			e.printStackTrace();
		}
		String byte2Hex = byte2Hex(result);
		return byte2Hex;
	}
	public static String imageFile2Hex(File imageFile) {
		FileInputStream fis;
		ByteArrayOutputStream bos;
		int len = 0;
		byte[] buff;
		byte[] result = null;
		try {
			fis = new FileInputStream(imageFile);
			bos = new ByteArrayOutputStream();
			buff = new byte[1024];
			while ((len = fis.read(buff)) != -1) {
				bos.write(buff, 0, len);
			}
			// 得到图片的字节数组
			result = bos.toByteArray();// 字节数组转成十六进制
		} catch (IOException e) {
			e.printStackTrace();
		}
		String byte2Hex = byte2Hex(result);
		return byte2Hex;
	}

	/**
	 * 实现字节数组向十六进制的转换方法一
	 * 
	 * @param bytes
	 * @return
	 * @author ServerZhang
	 * @date 2017年10月18日
	 */
	public static String byte2Hex(byte[] bytes) {
		String hs = "";
		String stmp = "";
		for (int n = 0, length = bytes.length; n < length; n++) {
			stmp = (Integer.toHexString(bytes[n] & 0XFF));
			if (stmp.length() == 1)
				hs = hs + "0" + stmp;
			else
				hs = hs + stmp;
		}
		return hs.toUpperCase();
	}
}
